Skip to content

[FIX] Honor 23.976 fps when importing SCC - #2452

Open
harshalsp07 wants to merge 2 commits into
CCExtractor:masterfrom
harshalsp07:fix/scc-23-976-input
Open

harshalsp07 wants to merge 2 commits into
CCExtractor:masterfrom
harshalsp07:fix/scc-23-976-input

Conversation

@harshalsp07

@harshalsp07 harshalsp07 commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

In raising this pull request, I confirm the following (please check boxes):

Reason for this PR:

  • This PR adds new functionality.
  • This PR fixes a bug that I have personally experienced or that a real user has reported and for which a sample exists.
  • This PR is porting code from C to Rust.

Sanity check:

  • I have read and understood the contributors guide.
  • I have checked that another pull request for this purpose does not exist.
  • If the PR adds new functionality, I've added it to the changelog. If it's just a bug fix, I have NOT added it to the changelog.
  • I am NOT adding new C code unless it's to fix an existing, reproducible bug.

--scc-framerate 23.976 and its 23.98 alias are accepted by the CLI, but SCC import silently uses 29.97 fps. Both spellings become integer value 4; SccFrameRate::from_int() doesn't handle it and falls back to the default.

Add the missing decoder rate and use 1001 / 24 milliseconds per frame. The other rate mappings stay the same.

Reproduce from the repository root with the included 90-byte sample:

ccextractor tests/samples/scc_23_976.scc --scc-framerate 23.976 -o out.srt

The sample contains HI between 00:00:01:12 and 00:00:03:12. On master d7eb132e, the SRT timing is 00:00:01,401 --> 00:00:03,399. With this change it is 00:00:01,501 --> 00:00:03,499. Repeating with 23.98 gives the same corrected timing.

Tested on Linux:

  • cargo test --locked in src/rust: 427 passed. The new SCC parsing test fails without the fix.
  • cargo fmt --all -- --check and cargo clippy -- -D warnings pass.
  • Release CMake build and 172 CLI runs checking all accepted frame-rate spellings, four frame offsets, BOM/CRLF, explicit SCC input and five output formats. All 70 comparisons for previously supported input and rates are byte-identical to master.

This fixes SCC input parsing. #2145 and #2406 concern CEA-708 SCC output timing. Windows/macOS and the external sample platform haven't been tested.

Follow-up local check on sample b22260d065 (platform regression 31): verified its SHA-256 and ran --autoprogram --out=srt --latin1 three times on master's source and three times on this branch, with the same compiler and dependencies. All six runs exit 0 and produce identical 161,874-byte SRT files (SHA-256 f5758a49bbe5fb46536c8a94b598f585ac0f92ac18bd451d862a8b3b57ecf561). Both builds start the first caption at 00:00:04,838, while the platform's approved output expects 00:00:02,635, so this does not establish an approved-output pass. The PR-specific difference reported by the hosted run was not reproduced locally; the platform test still needs a rerun.

CI note: The initial Linux build stops before compilation because libgpac-dev has no installation candidate on Ubuntu 26.04; #2428 addresses the runner change. The C format check also flags ccx_decoders_isdb.c and mp4.c, which are unchanged from master.

@cfsmp3 cfsmp3 closed this Nov 10, 2026
@cfsmp3 cfsmp3 reopened this Nov 10, 2026
@harshalsp07

Copy link
Copy Markdown
Contributor Author

sample 31 is byte-identical on master and this branch across 3 runs each. the approved first timestamp differs on both. could you rerun it?

@cfsmp3 cfsmp3 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is Carlos' claude doing the first pass. Before Carlos takes a look, please address these issues.

The fix is correct, and its timing model (wall seconds plus frames × 1001/24) matches our SCC writer in ccx_encoders_scc.c, so import and export round-trip. One thing left:

  • tests/samples/scc_23_976.scc is added but nothing references it. Either drop it, or use it in a test (for example, include_str! it in the new test_parse_scc_uses_23_976_framerate_from_ffi instead of the inline string).

The sample file was unreferenced. include_str! it in the FFI framerate
test and assert the parsed 608 byte pairs so both timing and content
are covered.
@ccextractor-bot

Copy link
Copy Markdown
Collaborator
CCExtractor CI platform finished running the test files on linux. 172/238 tests matched the approved output:
Report Name Tests Passed
Broken 9/13
CEA-708 2/14
DVB 0/7
DVD 3/3
DVR-MS 2/2
General 26/28
Hardsubx 1/1
Hauppage 3/3
MP4 3/3
NoCC 10/10
Options 69/86
Teletext 0/21
WTV 12/13
XDS 32/34

66 tests do not match the approved output. That is the pass/fail verdict. Whether this branch caused it is a separate question, answered below.


Compared with the tip of master — test 9984, commit 24d1e0a:

  • 0 pass there and fail here
  • 0 fail there and pass here
  • 0 fail on both, with different output
  • 66 fail on both, byte for byte the same

Compared with the commit this branch was cut from — test 9878, commit 185fe3f:

  • 0 pass there and fail here
  • 0 fail there and pass here
  • 0 fail on both, with different output
  • 66 fail on both, byte for byte the same

No test changes behaviour relative to the tip of master: every failure above fails there too, byte for byte. The approved output for those tests is out of date, which is a baseline to review rather than a regression in this branch.

@ccextractor-bot

Copy link
Copy Markdown
Collaborator
CCExtractor CI platform finished running the test files on windows. 130/238 tests matched the approved output:
Report Name Tests Passed
Broken 0/13
CEA-708 2/14
DVB 0/7
DVD 3/3
DVR-MS 0/2
General 1/28
Hardsubx 1/1
Hauppage 0/3
MP4 0/3
NoCC 10/10
Options 69/86
Teletext 0/21
WTV 12/13
XDS 32/34

108 tests do not match the approved output. That is the pass/fail verdict. Whether this branch caused it is a separate question, answered below.


Compared with the tip of master — test 9985, commit 24d1e0a:

  • 42 pass there and fail here
  • 0 fail there and pass here
  • 10 fail on both, with different output
  • 56 fail on both, byte for byte the same

Pass there, fail here:

Fail on both but produce different output — behaviour moved even though the verdict did not:

  • ccextractor --out=srt --latin1 611b4a9235...
  • ccextractor --autoprogram --out=ttxt --latin1 1020459a86...
  • ccextractor --autoprogram --out=srt --latin1 f1422b8bfe...
  • ccextractor --datapid 5603 --autoprogram --out=srt --latin1 --teletext 85c7fc1ad7...
  • ccextractor --autoprogram --out=srt --latin1 --quant 0 85271be4d2...
  • ccextractor --autoprogram --out=ttxt --latin1 --ucla dab1c1bd65...
  • ccextractor --autoprogram --out=srt --latin1 --tpage 299 b8c55aa2e9...
  • ccextractor --autoprogram --out=srt --latin1 --teletext --tpage 398 3b276ad8bf...
  • ccextractor --autoprogram --out=ttxt --latin1 b236a0590b...
  • ccextractor --out=srt --latin1 --autoprogram 29e5ffd34b...

Compared with the commit this branch was cut from — test 9693, commit af4b28d:

  • 0 pass there and fail here
  • 115 fail there and pass here
  • 32 fail on both, with different output
  • 76 fail on both, byte for byte the same
  • 1 have no result in that run

Fail on both but produce different output — behaviour moved even though the verdict did not:

Fail there, pass here:


This branch changes the behaviour of 52 test(s) relative to the tip of master. Those are the ones worth looking at; anything else in the list fails the same way on both sides.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants